home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*_______________________________________________________________________
- |
- | blixui.c - a faster ui and event handling
- |
- | this is based on ui.c and event.c, but largely rewritten, so it
- | does nothing more then nessecarry, and uses a switch statement,
- | instead of repeated testing (which is less flexible, but a lot
- | faster)
- | The ui.c and event.c programs were written by Gavin Bell, 1988
- |
- | (c) 1994 frans van hoesel Xtreme Graphics Software
- | hoesel@chem.rug.nl
- |
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <gl/gl.h>
- #include <gl/device.h>
- #include "config.h"
- #include "blix.h"
- #include "blixsound.h"
- #include "blixui.h"
- #include "blixmenu.h"
-
- /* Externally visible state: */
- int ui_quiet = FALSE;
- int ui_noisy = TRUE;
- int putbomb = 0; /* set to 1 when user hits space bar */
- int exitflag = 0; /* Becomes 1 when user quits */
- int uimode = MODE2D;
-
- /* States global to only this file */
- static int zoomflag = FALSE; /* When rotating with middle mouse */
- static int panflag = FALSE; /* Left AND Middle, zoom */
- static int rotateflag = FALSE; /* Left mouse, pan */
- static int mouse_noisy = FALSE; /* Interacting with mouse */
- long sizex, sizey; /* window size */
- static long origx, origy; /* window position */
- static short omx = (-1); /* old and new mouse position */
- static short omy = (-1); /* reset to -1 when mouse buttons go up */
- static short nmx = (-1);
- static short nmy = (-1);
- static int pop = 1;
-
- /* local prototypes */
- static void mouse_ui(void);
-
-
- /*_________________________________________________________________________
- |
- | ui_to_worldspace - map mouse position
- |
- | Map mouse click sx, sy to a more convenient (-1.0,1.0)
- | range, based on window size.
- */
-
- static void ui_to_worldspace(short sx, short sy, float * wx, float * wy) {
- (*wx) = (2.0 * sx) / (float) sizex - 1.0;
- (*wy) = (2.0 * sy) / (float) sizey - 1.0;
- }
-
- /*__________________________________________________________________
- |
- | ui - main event loop
- |
- | only returns when users exits.
- |
- */
-
- void ui(void) {
- short s;
- int device;
- int state;
-
- while (exitflag == 0 && uimode == MODE3D ) {
- if (qtest()) {
- device = (int) qread(&s);
- state = s;
- switch (device) {
-
- case REDRAW:
- reshapeviewport();
- getsize(&sizex, &sizey);
- getorigin(&origx, &origy);
- draw_whatever();
- break;
-
- case LEFTMOUSE:
- if (state == DOWN) {
- if (rotateflag == TRUE) {
- zoomflag = TRUE;
- rotateflag = FALSE;
- } else {
- panflag = TRUE;
- ui_noisy = mouse_noisy = TRUE;
- ui_quiet = !ui_noisy;
- }
- } else {
- /* 'officially' you should be rotating when
- * you came from zoommode and released the
- * left mouse button; that migth however be
- * annoying because it migth be true that you
- * simply released the left-moust 1 millisecond
- * before the middle one. As a 'fix' turn
- * everything off.
- */
- zoomflag = FALSE;
- rotateflag = FALSE;
- panflag = FALSE;
- mouse_noisy = FALSE;
- ui_noisy = rotateflag;
- ui_quiet = !ui_noisy;
- omx = omy = nmx = nmy = (-1);
- }
- mouse_ui();
- break;
-
- case MIDDLEMOUSE:
- if (state == DOWN) {
- if (panflag == TRUE) {
- zoomflag = TRUE;
- panflag = FALSE;
- } else {
- rotateflag = TRUE;
- mouse_noisy = TRUE;
- ui_noisy = TRUE;
- ui_quiet = !ui_noisy;
- }
- } else {
- if (zoomflag == TRUE) {
- zoomflag = FALSE;
- panflag = TRUE;
- } else {
- rotateflag = FALSE;
- mouse_noisy = FALSE;
- ui_noisy = panflag;
- ui_quiet = !ui_noisy;
- omx = omy = nmx = nmy = (-1);
- }
- }
- /* don't call mouse_ui here; it makes the interface
- * a bit tricky, because you might accidently cause
- * a big rotation. Not calling it now will delay it
- * by one frame
- */
- /*mouse_ui();*/
- break;
-
- case RIGHTMOUSE:
- if (state == DOWN && pop) {
- do_menus();
- }
- break;
-
- case ESCKEY:
- if (state == UP) {
- exitflag = 1;
- }
- break;
-
- case SPACEKEY:
- case BKEY:
- if (state == DOWN) {
- putbomb = 1;
- }
- break;
-
- case WINQUIT:
- case WINSHUT:
- exitflag = 1;
- break;
- }
- } else {
- if (mouse_noisy) {
- mouse_ui();
- } else {
- spin_draw();
- }
- }
- }
- }
-
-
- /*___________________________________________________________________
- |
- | mouse_ui - mouse interface
- |
- | maps the mouse coordinates on the virtual trackball, and calls
- | the trackball rotine to do the rotation.
- |
- */
-
- static void mouse_ui(void) {
- float r[4], t[3];
-
- if (mouse_noisy) {
- nmx = (short) getvaluator(CURSORX);
- if (omx == (-1)) omx = nmx;
- nmy = (short) getvaluator(CURSORY);
- if (omy == (-1)) omy = nmy;
- if (panflag != 0) {
- ui_to_worldspace((short)( nmx-origx), (short)(nmy-origy),
- t+1, t+2);
- t[0] = 0;
- remember_view(r, t);
- } else if (zoomflag !=0 ) {
- t[0] = 1;
- t[2] = (float)(nmy-omy)/(float)sizey;
- remember_view(r, t);
- } else if (rotateflag != 0) {
- float p1x, p1y, p2x, p2y ;
- t[0] = 2;
- ui_to_worldspace((short)( omx-origx), (short)(omy-origy),
- &p1x, &p1y);
- ui_to_worldspace((short)(nmx-origx), (short)(nmy-origy), &p2x, &p2y);
- trackball(r, p1x, p1y, p2x, p2y);
- remember_view(r, t);
- }
- omx = nmx; omy = nmy;
- }
- }
-
-
- /*_________________________________________________________________
- |
- | enter_redraw - queue a redraw event
- |
- */
-
- void enter_redraw(void) {
- qenter(REDRAW, 0);
- }
-
- /*__________________________________________________________________
- |
- | do_event - handle window events
- |
- | this routine is only used during the rather long initialization
- | procedure. The events are initialized in init_ui
- | it is called from player.c, but kept in this file for easy porting
- |
- */
-
- int do_event(void) {
- short s;
- int dev;
- int state;
-
- while (qtest()) {
- dev = (int)qread(&s);
- state = s;
- switch (dev) {
- case ESCKEY:
- if (s != 0)
- return 0;
- /* else run through to exit routine */
- case WINQUIT:
- case WINSHUT:
- exit_program();
- break;
- case REDRAW:
- reshapeviewport();
- getsize(&sizex, &sizey);
- getorigin(&origx, &origy);
- draw_whatever2d();
- break;
- case SPACEKEY:
- case LEFTMOUSE:
- if (state == UP) {
- return 1;
- }
- break;
- case RIGHTMOUSE:
- if (state == DOWN && pop) {
- do_menus();
- } else if (state == UP) {
- return 1;
- }
- break;
- }
- }
- return 0;
- }
-
- /*__________________________________________________________________
- |
- | disable_pop - disable the display of the popup menu
- |
- | call this routine when handling popup menues, so you don't
- | call them recursivly, which is not allowed by the GL.
- |
- */
-
- void disable_pop(void) {
- pop = 0;
- }
-
- void enable_pop(void) {
- pop = 1;
- }
-
-
- /*___________________________________________________________________
- |
- | init_ui - initialize user interface
- |
- | call this routine once from the main program.
- |
- */
-
- void init_ui(void) {
- getsize(&sizex, &sizey); /* Gotta know where center of */
- getorigin(&origx, &origy); /* window is */
- qdevice(ESCKEY);
- qdevice(WINQUIT);
- qdevice(WINSHUT);
- qdevice(BKEY); /* for the bombs from previous version of blix */
- qdevice(SPACEKEY); /* for the bombs */
- qdevice(REDRAW); /* Keep track of window size changes */
- qdevice(LEFTMOUSE);
- qdevice(MIDDLEMOUSE);
- qdevice(RIGHTMOUSE);
- /*qdevice(INPUTCHANGE);*/ /* I don't see any use for this */
-
- }
-
-